---
title: 'lighttpd + ipv6 + tls (dehydrated)'
url: /2022/04/lighttpd-ipv6/
draft: false
categories:
#- 🇬🇧
- en
- sysadmin
date: 2022-04-26 14:14:14+02:00
tags:
- lighttpd
- letsencrypt
- TLS
- ipv6
type: post
author: Marcus Rohrmoser
---

[Years after](../../../2015/12/lighttpd-letsencrypt-sh/) having set up letsencrypt with [dehydrated](https://dehydrated.io/) (a big thank you!), I was forced to revisit the configs due to an OS update ([devuan chimaera](https://www.devuan.org/os/announce/chimaera-release-announce-2021-10-14)).

And, finally, I wanted an ipv6 dual stack if possible. The prospect of having all lighttpd ssl configuration settings duplicated was unpleasant, however.

The final result came with a nice surprise in simplicity (line 18 and 19) because *no other ssl config* is required to achieve an [ssllabs](https://www.ssllabs.com/) 'A+' rate:

<pre class="line-numbers"><code class="language-lighttpd"># /etc/lighttpd/conf-available/12-tls-dehydrated.conf
$HTTP["scheme"] == "http" {
  # https://github.com/letsencrypt/letsencrypt/issues/94#issuecomment-156695088
  # http://redmine.lighttpd.net/projects/1/wiki/Docs_ModAlias
  # https://github.com/lukas2511/dehydrated/blob/master/docs/wellknown.md#lighttpd-example-config
  alias.url += (
    # must match WELLKNOWN in /var/www/dehydrate/config
    "/.well-known/acme-challenge/" => "/var/www/dehydrated/well-known/"
  )
}

# https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_SSL#Cipher-Selection
# https://ssl-config.mozilla.org/#server=lighttpd&version=1.4.59&config=intermediate&openssl=1.1.1n&guideline=5.6
server.modules += (
  "mod_openssl",
)

$SERVER["socket"] == ":443"     { ssl.engine = "enable" } # ipv4
$SERVER["socket"] == "[::]:443" { ssl.engine = "enable" } # ipv6

ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2")
ssl.openssl.ssl-conf-cmd += ("Options" => "-ServerPreference")
# TLS modules besides mod_openssl might name ciphers differently
# See https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_SSL
ssl.openssl.ssl-conf-cmd += ("CipherString" => "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384")

ssl.pemfile = "/var/www/dehydrated/certs/mro.name/privcert.pem"

include_shell "/etc/lighttpd/conf-available/12-tls-dehydrated.sh"
</code></pre>

With the companion dash script

<pre class="line-numbers"><code class="language-shell-session">#!/bin/sh
# /etc/lighttpd/conf-available/12-tls-dehydrated.sh
# find domain names with certs managed with https://dehydrated.io/

ls /var/www/dehydrated/certs/*/privcert.pem \
| while read -r pem
do
  # TODO replace . with \.
  dom="$(basename "$(dirname "${pem}")")"
  cat &lt;&lt;EOF
  $HTTP["host"] =~ "^(.+\.)?${dom}" { ssl.pemfile = "${pem}" }
EOF
done
</code></pre>

The only duplicate setting is enabling `ssl.engine` at all! Everything else suffices once in the global scope! And these settings come ready specific for the precise lighttpd version from [ssl-config.mozilla.org](https://ssl-config.mozilla.org/#server=lighttpd&version=1.4.59&config=intermediate&openssl=1.1.1n&guideline=5.6)!

Lighttpd brings the rest by default.

Activate that and be good:

<pre class="line-numbers"><code class="language-shell-session">$ sudo /usr/sbin/lighty-enable-mod tls-dehydrated
$ sudo service lighttpd restart
</code></pre>

